Skip to content

feat(i2c): Add i2c support and stabilize c_board transfer#41

Closed
gqsdjhh wants to merge 4 commits intoAlliance-Algorithm:mainfrom
gqsdjhh:i2c
Closed

feat(i2c): Add i2c support and stabilize c_board transfer#41
gqsdjhh wants to merge 4 commits intoAlliance-Algorithm:mainfrom
gqsdjhh:i2c

Conversation

@gqsdjhh
Copy link
Copy Markdown

@gqsdjhh gqsdjhh commented Apr 9, 2026

This PR adds end-to-end I2C support across the protocol, host SDK, and firmware.

It starts by introducing the I2C protocol and RmcsBoard support, then adds c_board I2C2 transport support, and finally improves c_board
reliability by replacing the previous queued interrupt-driven implementation with blocking HAL I2C transfers.

The main motivation for the last change is to avoid internal queue-overflow failures during bursty workloads such as OLED initialization and full-screen updates.

Included Changes

  • Add I2C protocol definitions and serializer/deserializer support
  • Add host-side I2C APIs for RmcsBoard
  • Add firmware-side I2C support for rmcs_board
  • Add host-side I2C APIs for CBoard
  • Add firmware-side I2C2 transport support for c_board
  • Configure the required c_board CubeMX I2C and interrupt plumbing
  • Replace queued async I2C handling on c_board with blocking HAL I2C operations
  • Keep the I2C address contract unchanged: host-provided slave addresses are still treated as 7-bit addresses

I2C 支持端到端实现与 c_board 传输稳定化(更新)

概览

本 PR 在协议、主机 SDK 与两块固件(c_board、rmcs_board)中实现了端到端的 I2C 支持,并通过将 c_board 的异步队列式 I2C 处理替换为基于 HAL 的阻塞/同步传输并加入 DMA 超时恢复逻辑,提升了在突发/高并发工作负载(例如 OLED 初始化与整屏更新)下的可靠性。保留主机端提供的从机地址为 7 位约定。

协议与数据结构

  • 新增 DataId::kI2c0 = 16。
  • 新增数据视图:
    • I2cDataView(slave_address,payload span,has_register/reg_address 可选寄存器字段)。
    • I2cReadConfigView(slave_address,read_length,has_register/reg_address)。
  • 新增协议位域 I2cHeader(PayloadType、HasRegister、ErrorFlag、SlaveAddress、DataLength),并定义 PayloadEnum(kWrite、kReadRequest、kReadResult、kError)。
  • 扩展回调接口(DataCallback / DeserializeCallback / 反序列化钩子):新增 I2C 相关回调用于写、读请求、读结果与错误通知;新增 i2c_receive_callback 与 i2c_error_callback。

序列化与反序列化

  • Serializer:新增 write_i2c_write、write_i2c_read_config、write_i2c_read_result、write_i2c_error 及 required_i2c_size 校验/计算逻辑;参数校验(包括 slave_address ≤ 0x7F)与条件性寄存器/负载写入。
  • Deserializer:新增 process_i2c_field 协程,解析 I2cHeader、可选寄存器字节并按 PayloadType 分发到相应反序列化回调;在字节不足或未知类型时安全进入丢弃模式并返回失败。

c_board 固件(STM32F4)— 主要更改与稳健性改进

  • 引入基于 HAL 的 I2C 支持(I2C2),CubeMX 配置、i2c.c/i2c.h、NVIC 与 DMA 流配置已添加;在 main/init 中调用 MX_I2C2_Init() 与 i2c0.init(),并在主循环中更新 i2c 实例。
  • 新增 librmcs::firmware::i2c::I2c 类(c_board):以前为队列/中断驱动的异步实现被替换为以 HAL I2C(DMA 驱动)为基础的阻塞式传输策略(在实现中通过启动 HAL DMA 操作并使用完成/错误回调完成请求)。对输入做边界检查(最大长度、空负载等)。
  • 增加 DMA 超时恢复逻辑:当在-flight 传输超时,abort DMA、deinit/reinit HAL I2C handle,并将该传输完成为错误,提升在 DMA/总线异常情况下的恢复能力(提交/commit 中的修复 commit)。
  • 中断回调(HAL_*Cplt / HAL_*ErrorCallback)被桥接到 C++ I2c 实例以完成请求处理并通过 USB 序列化器上报读结果或错误。
  • USB 下行反序列化回调已集成:DataId::kI2c0 的写/读请求被路由到 i2c::i2c0 的处理函数;上行读结果与错误由设备端序列化上报主机。
  • CMake/构建:将 i2c.c 与 stm32 HAL I2C 实现加入构建,stm32f4xx_hal_conf.h 启用 HAL_I2C_MODULE_ENABLED。

rmcs_board 固件(HPM SDK)

  • 新增 librmcs::firmware::i2c::I2c(HPM 平台实现),封装初始化与下行处理,支持寄存器寻址与原始从机访问,读成功后序列化 read result,上报错误时序列化 error。
  • 提供全局单例 i2c0(基于 HPM_I2C0_BASE 或可配置 BOARD_APP_I2C_BASE)。
  • 更新了 hpm_sdk 子模块指针以包含所需 SDK 更改。

主机端(host)API 与协议层

  • RmcsBoard / CBoard:
    • PacketBuilder 新增 i2c0_write(const I2cDataView&) 与 i2c0_read(const I2cReadConfigView&)(输入验证,空负载 / 零读取长度抛出 invalid_argument)。
    • 新增虚拟回调钩子 i2c0_receive_callback(const I2cDataView&) 与 i2c0_error_callback(uint8_t),默认空操作;并实现对 DataId::kI2c0 的路由覆盖。
  • 协议处理层(Handler):
    • PacketBuilder 新增 write_i2c、write_i2c_read_config、write_i2c_read_result 等方法,将高层数据封装并交给 Serializer。
    • 新增上行反序列化处理:上行读结果转发到 callback_.i2c_receive_callback,错误转发到 callback_.i2c_error_callback;对非预期上行写/读请求记录错误。

关键设计决策与注意点

  • 从机地址约定:主机侧继续使用 7 位地址(≤ 0x7F);firmware 在调用 HAL 接口时根据 HAL 要求做左移处理(适配 8 位格式)。
  • 传输模型:为应对 bursty 工作负载,c_board 采用阻塞/同步 HAL I2C 传输并配合 DMA;为处理 DMA 或总线异常,新增超时检测与 DMA 恢复(abort、deinit/reinit)以避免长期卡死或队列积压导致丢失/阻塞。
  • 寄存器寻址:通过 has_register 标志选择使用 HAL_I2C_Mem_(带寄存器)或 HAL_I2C_Master_(无寄存器)路径。
  • 错误上报:在固件端读取/写入失败时通过 USB 序列化器发送 i2c_error 给主机;主机端提供回调供上层处理。

影响范围 & 兼容性

  • 向后兼容性:保持主机 7 位地址契约;新增协议字段与 DataId 不会影响非 I2C 流量。
  • 需要注意:c_board 的 HAL/中断/DMA 配置、CubeMX 项目和构建文件已改动,更新固件构建环境时需同步这些更改(新增 i2c.c、HAL I2C 源文件与 IRQ/DMA 配置)。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

Walkthrough

添加对 I2C 的端到端支持:数据结构与枚举扩展、协议序列化/反序列化钩子、主机端/固件端 I2C 报文构建与路由、STM32/HPM 平台的 I2C 驱动与中断/DMA 集成,以及相关构建配置与子模块更新(GPIO/IRQ/DMA 配置、CubeMX 项目调整)。

Changes

Cohort / File(s) Summary
核心数据与协议
core/include/librmcs/data/datas.hpp, core/src/protocol/protocol.hpp
新增 DataId::kI2c0I2cDataViewI2cReadConfigView,并添加 I2cHeader 位域协议定义。
序列化/反序列化
core/src/protocol/serializer.hpp, core/src/protocol/deserializer.hpp, core/src/protocol/deserializer.cpp
扩展 DeserializeCallback/Serializer 接口,新增 I2C 写/读请求/读结果/错误 的序列化方法与反序列化协程 process_i2c_field() 及相关回调路由与验证。
Core 回调接口
core/include/librmcs/data/datas.hpp
DataCallback 中添加 i2c_receive_callback(...)i2c_error_callback(...) 纯虚方法。
STM32 固件(C_Board)
firmware/c_board/bsp/cubemx/..., firmware/c_board/app/src/i2c/*, firmware/c_board/app/src/usb/vendor.hpp, firmware/c_board/app/src/app.cpp
新增 I2C HAL 驱动(i2c.c/.h)、中断/DMA 处理、CubeMX 配置与 C++ 封装类,USB 端点反序列化路由并在主循环调用 i2c 实例更新。
RMCS Board 固件(HPM)
firmware/rmcs_board/app/src/i2c/i2c.hpp, firmware/rmcs_board/app/src/usb/vendor.hpp, firmware/rmcs_board/app/src/app.cpp, firmware/rmcs_board/bsp/hpm_sdk
添加 HPM 平台 I2C 封装、下行处理与上行结果序列化;更新 hpm_sdk 子模块引用以包含 I2C 支持。
主机代理/协议层
host/include/librmcs/agent/c_board.hpp, host/include/librmcs/agent/rmcs_board.hpp, host/include/librmcs/protocol/handler.hpp, host/src/protocol/handler.cpp
为 CBoard/RmcsBoard 的 PacketBuilder 增加 i2c0_write/i2c0_read,在主机 Handler 中新增 I2C 写/读/读结果/错误 的处理与回调转发。
工具链/构建/配置
firmware/c_board/bsp/cubemx/rmcs_slave.ioc, firmware/c_board/bsp/cubemx/CMakeLists.txt, firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_hal_conf.h
更新 CubeMX 项目以包含 I2C2、添加 I2C 源到 CMake,启用 HAL I2C 模块与相关 NVIC/DMA 条目。
其他小改动
firmware/c_board/bsp/cubemx/Core/Src/gpio.c, firmware/c_board/bsp/cubemx/Core/Src/dma.c, firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.h, firmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.c
新增/调整 GPIOF 时钟使能、DMA IRQ 初始化、并添加/启用 I2C2 相关 IRQ 处理器和原型。

Sequence Diagram(s)

sequenceDiagram
    participant Host as Host
    participant Serializer as Serializer
    participant USB as USB
    participant Deserializer as Deserializer
    participant Handler as Handler
    participant I2Cdrv as I2C Driver
    participant HAL as HAL

    Host->>Serializer: write_i2c_write(kI2c0, data)
    Serializer->>USB: send bytes
    USB->>Deserializer: receive bytes
    Deserializer->>Deserializer: process_i2c_field()
    Deserializer->>Handler: i2c_write_deserialized_callback()
    Handler->>I2Cdrv: handle_downlink_write()
    I2Cdrv->>HAL: start DMA Tx/Rx or Mem_Read/Mem_Write
    HAL-->>I2Cdrv: completion or error

    alt success
        I2Cdrv->>Handler: complete
    else error
        I2Cdrv->>Serializer: write_i2c_error()
        Serializer->>USB: send error
    end
Loading

估算代码审查工作量

🎯 4 (复杂) | ⏱️ ~50 分钟

可能相关的PR

诗歌

🐰 跳过线与字节的沟壑,
我把寄存器轻轻敲,读与写像胡萝卜的呼唤,
中断与 DMA 一起跳舞,回包沿着 USB 回家,
小小地址左移一位,数据在总线上嗡嗡唱,
我是代码里的兔子,庆祝协议的新芽绽放。

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确总结了PR的主要改动:实现I2C协议支持并改进c_board的传输可靠性。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
firmware/c_board/app/src/app.cpp (1)

86-86: 建议明确 Line 86 的 no-op 调用意图。

Line 86 当前调用 i2c::i2c0->update(),但 firmware/c_board/app/src/i2c/i2c.hppupdate() 为空实现。建议加注释说明“保留扩展点”,避免后续维护误判。

可选改进示例
-        i2c::i2c0->update();
+        // Keep this call as an extension point for future non-blocking I2C work.
+        i2c::i2c0->update();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/c_board/app/src/app.cpp` at line 86, 在调用 i2c::i2c0->update() 的位置(当前在
app.cpp 第 86 行)明确说明这是一处空实现的保留扩展点:在调用旁边添加注释,注明 i2c::I2C::update() 在
firmware/c_board/app/src/i2c/i2c.hpp
中目前为空实现、用于未来扩展或平台特定实现,并指明不要删除或误以为是忘写逻辑;同时报错/断言等不可行时保持调用以便兼容未来实现。
host/include/librmcs/agent/rmcs_board.hpp (1)

75-85: 考虑添加 [[unlikely]] 属性以保持一致性。

c_board.hpp 中的 i2c0_writei2c0_read 方法在错误条件上使用了 [[unlikely]] 属性,但此文件缺少该属性。建议保持两个 board 实现的一致性。

♻️ 建议的修改
     PacketBuilder& i2c0_write(const librmcs::data::I2cDataView& data) {
-        if (data.payload.empty() || !builder_.write_i2c(data::DataId::kI2c0, data))
+        if (data.payload.empty() || !builder_.write_i2c(data::DataId::kI2c0, data)) [[unlikely]]
             throw std::invalid_argument{"I2C0 write failed: Invalid I2C data"};
         return *this;
     }

     PacketBuilder& i2c0_read(const librmcs::data::I2cReadConfigView& data) {
-        if (data.read_length == 0 || !builder_.write_i2c_read_config(data::DataId::kI2c0, data))
+        if (data.read_length == 0 || !builder_.write_i2c_read_config(data::DataId::kI2c0, data))
+            [[unlikely]]
             throw std::invalid_argument{"I2C0 read failed: Invalid I2C read config"};
         return *this;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@host/include/librmcs/agent/rmcs_board.hpp` around lines 75 - 85, The error
branches in PacketBuilder::i2c0_write and PacketBuilder::i2c0_read lack the
[[unlikely]] attribute used in the c_board.hpp equivalent; update the
conditional checks so the throw paths are annotated with [[unlikely]] (i.e.,
mark the failing condition as unlikely when checking data.payload.empty() or
data.read_length == 0 and the builder_.write_* calls) to match the other board
implementation and maintain consistency between i2c0_write and i2c0_read error
branches.
firmware/c_board/app/src/i2c/i2c.hpp (1)

28-40: 空 payload 静默返回 vs 发送错误通知 - 建议对齐行为。

payload.empty() 时,此方法静默返回(line 29-30),而当 payload.size() > kMaxDataLength 时发送错误通知(line 32-35)。

对比 rmcs_board 版本的 handle_downlink_write(同样静默返回),两者行为一致。但从协议角度,主机端可能期望收到反馈。如果这是预期行为(空写入不是错误),可以添加注释说明设计意图。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/c_board/app/src/i2c/i2c.hpp` around lines 28 - 40, The function
handle_downlink_write currently returns silently when data.payload.empty() but
sends an error when payload.size() > kMaxDataLength, causing inconsistent host
feedback; update handle_downlink_write to either call
write_error(data.slave_address) for empty payloads to align behavior with
oversized payloads, or add a clear code comment above the empty-payload check
explaining that an empty write is intentionally treated as a no-op and not an
error (and reference write_error, kMaxDataLength, and write_blocking in the
comment to clarify the contract).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@firmware/c_board/bsp/cubemx/Core/Src/i2c.c`:
- Around line 85-88: 当前在 i2c.c 中对 I2C2 事件/错误中断使用 HAL_NVIC_SetPriority(..., 0, 0)
并启用 IRQ (HAL_NVIC_EnableIRQ(I2C2_EV_IRQn)/HAL_NVIC_EnableIRQ(I2C2_ER_IRQn)),会与
USB (OTG_FS_IRQn) 冲突且你的传输调用 HAL_I2C_Master_Transmit()/HAL_I2C_Master_Receive()
是阻塞式,不需要中断;请在配置中将 I2C2_EV_IRQn 和 I2C2_ER_IRQn 的优先级改为 HAL_NVIC_SetPriority(...,
1, 0) 或直接移除/注释掉对应的 HAL_NVIC_EnableIRQ 调用(如果不需要错误中断处理),并确保修改发生在配置 I2C2
中断的初始化函数(查找 HAL_NVIC_SetPriority / HAL_NVIC_EnableIRQ 对 I2C2 的调用处)。

In `@firmware/rmcs_board/app/src/i2c/i2c.hpp`:
- Around line 58-60: handle_downlink_read_config currently silently returns when
data.read_length is 0 or > kMaxDataLength; change this to send the same I2C
error notification the c_board implementation uses instead of silent return. In
the handle_downlink_read_config function (and when validating
data::I2cReadConfigView.read_length against kMaxDataLength) emit the I2C error
notification/response (use the project’s existing notify/send I2C error API used
by the c_board codebase) with a descriptive error reason before returning so the
host receives the error feedback.
- Around line 32-56: handle_downlink_write currently omits a payload size limit
check: before using data.payload in i2c_master_write/i2c_master_address_write
validate that data.payload.size() <= kMaxDataLength (same limit used in
c_board), and if it exceeds, call
usb::get_serializer().write_i2c_error(data_id_, data.slave_address) (assert on
non-kInvalidArgument like existing error paths) and return; reference symbols:
handle_downlink_write, data::I2cDataView, kMaxDataLength, write_i2c_error,
data_id_.

In `@firmware/rmcs_board/bsp/hpm_sdk`:
- Line 1: 回退移除了 GPIO 初始化(board_init_gpio_pins)和 Flash/XPI 配置,可能破坏依赖于 GPIO 状态的
HAL I2C 传输;请在 PR 中补充回退原因与兼容性评估、并在代码里恢复或有条件调用
board_init_gpio_pins()(或提供替代初始化路径)以保证 I2C 初始化/传输和中断处理行为一致;在本地或 CI 运行覆盖性验证:1) 验证
HAL I2C init/transfer 在无 board_init_gpio_pins 情况下是否失败;2) 验证中断和 I/O 线路的电平/复用设置;3)
恢复或迁移 Flash/XPI NOR board 配置并记录任何行为差异;在 PR 描述中列出对比 a82a5354 与 132349c9
的差异、测试结果和最终决定(恢复、条件初始化或明确不兼容)。

---

Nitpick comments:
In `@firmware/c_board/app/src/app.cpp`:
- Line 86: 在调用 i2c::i2c0->update() 的位置(当前在 app.cpp 第 86
行)明确说明这是一处空实现的保留扩展点:在调用旁边添加注释,注明 i2c::I2C::update() 在
firmware/c_board/app/src/i2c/i2c.hpp
中目前为空实现、用于未来扩展或平台特定实现,并指明不要删除或误以为是忘写逻辑;同时报错/断言等不可行时保持调用以便兼容未来实现。

In `@firmware/c_board/app/src/i2c/i2c.hpp`:
- Around line 28-40: The function handle_downlink_write currently returns
silently when data.payload.empty() but sends an error when payload.size() >
kMaxDataLength, causing inconsistent host feedback; update handle_downlink_write
to either call write_error(data.slave_address) for empty payloads to align
behavior with oversized payloads, or add a clear code comment above the
empty-payload check explaining that an empty write is intentionally treated as a
no-op and not an error (and reference write_error, kMaxDataLength, and
write_blocking in the comment to clarify the contract).

In `@host/include/librmcs/agent/rmcs_board.hpp`:
- Around line 75-85: The error branches in PacketBuilder::i2c0_write and
PacketBuilder::i2c0_read lack the [[unlikely]] attribute used in the c_board.hpp
equivalent; update the conditional checks so the throw paths are annotated with
[[unlikely]] (i.e., mark the failing condition as unlikely when checking
data.payload.empty() or data.read_length == 0 and the builder_.write_* calls) to
match the other board implementation and maintain consistency between i2c0_write
and i2c0_read error branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99e630ac-7991-4c1f-89de-584c2a600765

📥 Commits

Reviewing files that changed from the base of the PR and between e9675db and 12bce2b.

📒 Files selected for processing (26)
  • .codex
  • core/include/librmcs/data/datas.hpp
  • core/src/protocol/deserializer.cpp
  • core/src/protocol/deserializer.hpp
  • core/src/protocol/protocol.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/app.cpp
  • firmware/c_board/app/src/i2c/i2c.hpp
  • firmware/c_board/app/src/usb/vendor.hpp
  • firmware/c_board/bsp/cubemx/Core/Inc/i2c.h
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_hal_conf.h
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.h
  • firmware/c_board/bsp/cubemx/Core/Src/gpio.c
  • firmware/c_board/bsp/cubemx/Core/Src/i2c.c
  • firmware/c_board/bsp/cubemx/Core/Src/main.c
  • firmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.c
  • firmware/c_board/bsp/cubemx/cmake/stm32cubemx/CMakeLists.txt
  • firmware/c_board/bsp/cubemx/rmcs_slave.ioc
  • firmware/rmcs_board/app/src/app.cpp
  • firmware/rmcs_board/app/src/i2c/i2c.hpp
  • firmware/rmcs_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/bsp/hpm_sdk
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board.hpp
  • host/include/librmcs/protocol/handler.hpp
  • host/src/protocol/handler.cpp

Comment thread firmware/c_board/bsp/cubemx/Core/Src/i2c.c Outdated
Comment thread firmware/rmcs_board/app/src/i2c/i2c.hpp
Comment thread firmware/rmcs_board/app/src/i2c/i2c.hpp
@@ -1 +1 @@
Subproject commit a82a53544d5679a43b70f390c8bbbb8e91f6b8c1
Subproject commit 132349c9ddad3cbeca7211345d5d6086355f20b9
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Submodule pointer change =="
git diff --submodule=log origin/main...HEAD -- firmware/rmcs_board/bsp/hpm_sdk || true

echo
echo "== .gitmodules entry =="
sed -n '/firmware\/rmcs_board\/bsp\/hpm_sdk/,+5p' .gitmodules || true

echo
echo "== Old/New gitlinks =="
echo "[origin/main]"
git ls-tree origin/main -- firmware/rmcs_board/bsp/hpm_sdk || true
echo
echo "[HEAD]"
git ls-tree HEAD -- firmware/rmcs_board/bsp/hpm_sdk || true

Repository: Alliance-Algorithm/librmcs

Length of output: 676


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if hpm_sdk submodule is initialized =="
if [ -d "firmware/rmcs_board/bsp/hpm_sdk/.git" ]; then
  echo "✓ Submodule is initialized"
  
  cd firmware/rmcs_board/bsp/hpm_sdk
  echo
  echo "== Commit log between old and new commit =="
  git log --oneline a82a53544d5679a43b70f390c8bbbb8e91f6b8c1..132349c9ddad3cbeca7211345d5d6086355f20b9 || true
  echo
  
  echo "== Detailed commit info for new commit =="
  git show --stat 132349c9ddad3cbeca7211345d5d6086355f20b9 | head -100 || true
  
else
  echo "✗ Submodule not initialized locally"
  echo "Submodule path: firmware/rmcs_board/bsp/hpm_sdk"
fi

Repository: Alliance-Algorithm/librmcs

Length of output: 201


🌐 Web query:

site:github.com/Alliance-Algorithm/hpm_sdk compare a82a53544d5679a43b70f390c8bbbb8e91f6b8c1...132349c9ddad3cbeca7211345d5d6086355f20b9

💡 Result:

GitHub shows no changes to compare between these commits: a82a5354... already contains all commits from 132349c9... (i.e., 132349c9... is behind / an ancestor of a82a5354...). (github.com)

If you want to see the reverse difference, switch the base/head (compare 132349c9... as base against a82a5354... as head). (github.com)

Citations:


🌐 Web query:

site:github.com/Alliance-Algorithm/hpm_sdk compare 132349c9ddad3cbeca7211345d5d6086355f20b9...a82a53544d5679a43b70f390c8bbbb8e91f6b8c1

💡 Result:

Comparison 132349c9ddad3cbeca7211345d5d6086355f20b9...a82a53544d5679a43b70f390c8bbbb8e91f6b8c1 in Alliance-Algorithm/hpm_sdk contains 1 commit (“iter1”, committed Mar 31, 2026 by qzhhhi), touching 2 files with +13 / -3 lines. GitHub couldn’t render the full compare view (“taking too long to generate”), but the commit diff is visible. [1][2]

Changes:

  • boards/hpm5300evk/board.c: adds a new function board_init_gpio_pins() that sets the app GPIO pin as input via gpio_set_pin_input(...). [2]
  • boards/hpm5300evk/board.h:
    • adds board flash/XPI NOR related defines: BOARD_FLASH_BASE_ADDRESS, BOARD_FLASH_SIZE, BOARD_APP_XPI_NOR_XPI_BASE, and BOARD_APP_XPI_NOR_CFG_OPT_*. [2]
    • changes the board_init_gpio_pins declaration from commented-out to enabled (void board_init_gpio_pins(void);). [2]

Sources: [1] compare view, [2] commit a82a535 diff.


这是版本回退,移除了 GPIO 初始化代码——需要明确说明回退原因和兼容性影响。

这次变更并非升级,而是从 a82a5354 回退到其祖先 132349c9。被回退的 commit(2026-03-31)移除了:

  • board_init_gpio_pins() 函数及其 GPIO 初始化逻辑
  • Flash/XPI NOR 相关的 board 配置定义

当前 PR 直接依赖 HAL I2C 传输,如果 I2C 初始化或数据线依赖于 board_init_gpio_pins() 的 GPIO 状态配置,这个回退可能导致 I2C 传输失败。PR 缺少:

  • 说明为什么需要此次回退
  • GPIO 初始化被移除后的兼容性验证
  • I2C/中断处理与 GPIO 初始化间的依赖关系说明

请补充这些信息或在本地完整验证后再提交。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/rmcs_board/bsp/hpm_sdk` at line 1, 回退移除了 GPIO
初始化(board_init_gpio_pins)和 Flash/XPI 配置,可能破坏依赖于 GPIO 状态的 HAL I2C 传输;请在 PR
中补充回退原因与兼容性评估、并在代码里恢复或有条件调用 board_init_gpio_pins()(或提供替代初始化路径)以保证 I2C
初始化/传输和中断处理行为一致;在本地或 CI 运行覆盖性验证:1) 验证 HAL I2C init/transfer 在无
board_init_gpio_pins 情况下是否失败;2) 验证中断和 I/O 线路的电平/复用设置;3) 恢复或迁移 Flash/XPI NOR
board 配置并记录任何行为差异;在 PR 描述中列出对比 a82a5354 与 132349c9
的差异、测试结果和最终决定(恢复、条件初始化或明确不兼容)。

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
firmware/c_board/bsp/cubemx/Core/Src/dma.c (1)

47-61: 建议将新增段落调整为 4 空格缩进以符合仓库规范。

当前新增 NVIC 配置仍是 2 空格缩进;建议在本次改动中统一为 4 空格,避免后续格式漂移。

As per coding guidelines "Use 4 space indentation with 100 column width limit".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/c_board/bsp/cubemx/Core/Src/dma.c` around lines 47 - 61, The newly
added NVIC configuration lines use 2-space indentation; update the block so each
line is indented with 4 spaces to match the repository style. Locate the calls
to HAL_NVIC_SetPriority and HAL_NVIC_EnableIRQ (e.g., for DMA1_Stream1_IRQn,
DMA1_Stream2_IRQn, DMA1_Stream3_IRQn, DMA1_Stream7_IRQn, DMA2_Stream0_IRQn) in
dma.c and reformat those lines to use 4-space leading indentation consistently.
firmware/rmcs_board/app/src/i2c/i2c.hpp (1)

41-51: 为 HAL I2C 写接口参数添加注释说明,或考虑使用可写缓冲区副本。

payload 来自 std::span<const std::byte>(只读),通过 const_cast 传给 i2c_master_write()i2c_master_address_write() 时,隐含依赖 HPM I2C 驱动"不会修改发送缓冲区"的契约。HPM SDK 的 API 设计(使用 uint8_t* 而非 const uint8_t*)导致这种类型转换必要,但缺乏文档保证。建议:(1) 参考 interrupt_safe_buffer.hpp:99 的模式,添加 NOLINT 和注释说明原因,或 (2) 改为拷贝到内部可写缓冲区再调用驱动。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@firmware/rmcs_board/app/src/i2c/i2c.hpp` around lines 41 - 51, The code
const_casts a read-only payload (payload from std::span<const std::byte>) and
passes it to i2c_master_write / i2c_master_address_write, relying on an
undocumented driver promise not to modify the buffer; fix by either (A) making
the contract explicit: add a clear comment above the const_cast referencing
payload, i2c_master_write, and i2c_master_address_write and add an appropriate
NOLINT suppression exactly where const_cast is used, or (B) eliminate the
const_cast by copying the payload into a local writable buffer (e.g.,
std::vector<uint8_t> or an interrupt-safe buffer) and pass that buffer's data to
i2c_master_write / i2c_master_address_write; implement one of these two options
and ensure reg_address handling stays the same when calling
i2c_master_address_write.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@firmware/c_board/bsp/cubemx/Core/Src/dma.c`:
- Around line 47-61: The newly added NVIC configuration lines use 2-space
indentation; update the block so each line is indented with 4 spaces to match
the repository style. Locate the calls to HAL_NVIC_SetPriority and
HAL_NVIC_EnableIRQ (e.g., for DMA1_Stream1_IRQn, DMA1_Stream2_IRQn,
DMA1_Stream3_IRQn, DMA1_Stream7_IRQn, DMA2_Stream0_IRQn) in dma.c and reformat
those lines to use 4-space leading indentation consistently.

In `@firmware/rmcs_board/app/src/i2c/i2c.hpp`:
- Around line 41-51: The code const_casts a read-only payload (payload from
std::span<const std::byte>) and passes it to i2c_master_write /
i2c_master_address_write, relying on an undocumented driver promise not to
modify the buffer; fix by either (A) making the contract explicit: add a clear
comment above the const_cast referencing payload, i2c_master_write, and
i2c_master_address_write and add an appropriate NOLINT suppression exactly where
const_cast is used, or (B) eliminate the const_cast by copying the payload into
a local writable buffer (e.g., std::vector<uint8_t> or an interrupt-safe buffer)
and pass that buffer's data to i2c_master_write / i2c_master_address_write;
implement one of these two options and ensure reg_address handling stays the
same when calling i2c_master_address_write.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c4e3286-1e73-4326-aada-8cad3be0ded6

📥 Commits

Reviewing files that changed from the base of the PR and between 12bce2b and 20ea882.

📒 Files selected for processing (9)
  • firmware/c_board/app/src/i2c/i2c.cpp
  • firmware/c_board/app/src/i2c/i2c.hpp
  • firmware/c_board/bsp/cubemx/Core/Inc/i2c.h
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.h
  • firmware/c_board/bsp/cubemx/Core/Src/dma.c
  • firmware/c_board/bsp/cubemx/Core/Src/i2c.c
  • firmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.c
  • firmware/c_board/bsp/cubemx/rmcs_slave.ioc
  • firmware/rmcs_board/app/src/i2c/i2c.hpp
🚧 Files skipped from review as they are similar to previous changes (5)
  • firmware/c_board/bsp/cubemx/Core/Inc/i2c.h
  • firmware/c_board/bsp/cubemx/Core/Src/stm32f4xx_it.c
  • firmware/c_board/bsp/cubemx/Core/Inc/stm32f4xx_it.h
  • firmware/c_board/bsp/cubemx/Core/Src/i2c.c
  • firmware/c_board/bsp/cubemx/rmcs_slave.ioc

@gqsdjhh gqsdjhh closed this Apr 11, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in RMCS Slave SDK Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant